package kr.pe.johnkim.waiting.mobile.service;

import kr.pe.johnkim.waiting.mobile.dao.WaitingUserDao;
import kr.pe.johnkim.waiting.mobile.domain.WaitingUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Waiting 사용자 관련 service 구현 클래스 이다.
 *
 * @author : John_Kim <cale9797@gmail.com>
 * @date : 13. 4. 10.
 */
@Service
public class WaitingUserServiceImpl implements WaitingUserService {

    // SLF4J Logging
    private Logger logger = LoggerFactory.getLogger(WaitingUserServiceImpl.class);

    @Autowired
    private WaitingUserDao waitingUserDao;

    /**
     * 이미 등록된 사용자 대기가 있는지 확인한다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectDuplicationUser(WaitingUser waitingUser) {
        logger.info("selectDuplicationUser");
        return this.waitingUserDao.selectDuplicationUser(waitingUser);
    }

    /**
     * 사용자가 대기 등록된 가맹점의 정보를 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserMerchantInformation(WaitingUser waitingUser) {
        logger.info("selectUserMerchantInformation");
        return this.waitingUserDao.selectUserMerchantInformation(waitingUser);
    }

    /**
     * (오늘) 다음 대기번호를 가져 온다.
     * 한번 대기 등록되었던 갯수를 모두 가져 온다.
     * 이 숫자에 1을 더해서 대기번호로 사용 한다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectNumberWaiting(WaitingUser waitingUser) {
        logger.info("selectNumberWaiting");
        return this.waitingUserDao.selectNumberWaiting(waitingUser);
    }

    /**
     * 대기를 등록 한다.
     *
     * @param waitingUser
     */
    @Override
    public void registerUser(WaitingUser waitingUser) {
        logger.info("registerUser");
        this.waitingUserDao.registerUser(waitingUser);
    }

    /**
     * 다른 대기자가 없을 경우 해당 사용자를 대기자로 등록하고 next_turn_yn 을 업데이트 한다.
     *
     * @param waitingUser
     */
    @Override
    public void registerUserAndUpdateNextTurnYn(WaitingUser waitingUser) {
        logger.info("registerUserAndUpdateNextTurnYn");

        this.waitingUserDao.registerUser(waitingUser);

        // 등록된 대기 사용자 정보를 가져 온다.
        WaitingUser parameter = new WaitingUser();

        parameter.setMerchantId(waitingUser.getMerchantId());
        if(!("").equals(waitingUser.getUserName())) {
            parameter.setUserName(waitingUser.getUserName());
            parameter.setQrCode("");
            parameter.setPhoneNumber("");
        } else if(!("").equals(waitingUser.getQrCode())) {
            parameter.setUserName("");
            parameter.setQrCode(waitingUser.getQrCode());
            parameter.setPhoneNumber("");
        } else if(!("").equals(waitingUser.getPhoneNumber())) {
            parameter.setUserName("");
            parameter.setQrCode("");
            parameter.setPhoneNumber(waitingUser.getPhoneNumber());
        }
        parameter.setActivateYn(waitingUser.getActivateYn());

        String idWaitingUsers = this.waitingUserDao.selectUserInformation(parameter).getIdWaitingUsers();

        // 대기 사용자의 next_turn_yn 값을 'Y' 로 업데이트 한다.
        WaitingUser parameterUpdate = new WaitingUser();

        parameterUpdate.setMerchantId(waitingUser.getMerchantId());
        parameterUpdate.setIdWaitingUsers(idWaitingUsers);
        parameterUpdate.setNextTurnYn(waitingUser.getNextTurnYn());
        parameterUpdate.setAdmissionYn(waitingUser.getAdmissionYn());
        parameterUpdate.setModifyDate(waitingUser.getModifyDate());

        this.waitingUserDao.updateUserNextTurnYn(waitingUser);
    }

    /**
     * 등록된 대기 정보를 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserInformation(WaitingUser waitingUser) {
        logger.info("selectUserInformation");
        return this.waitingUserDao.selectUserInformation(waitingUser);
    }

    /**
     * 사용자 id 로 등록된 대기 정보를 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserInformationById(WaitingUser waitingUser) {
        logger.info("selectUserInformationById");
        return this.waitingUserDao.selectUserInformationById(waitingUser);
    }

    /**
     * 대기를 취소 한다. 대기를 등록했다가 취소하는 경우 비활성화 한다.
     *
     * @param waitingUser
     */
    @Override
    public void updateDeactivateUser(WaitingUser waitingUser) {
        logger.info("updateDeactivateUser");
        this.waitingUserDao.updateDeactivateUser(waitingUser);
    }

    /**
     * 대기를 취소 한다. 다음 대기자의 next_turn_yn 의 값을 'Y' 로 업데이트 한다.
     *
     * @param waitingUser
     */
    @Override
    public void updateDeactivateUserAndUserNextTurnYn(WaitingUser waitingUser) {
        logger.info("updateDeactivateUserAndUserNextTurnYn");

        WaitingUser parameter01 = new WaitingUser();

        parameter01.setIdWaitingUsers(waitingUser.getIdWaitingUserDeactivateYn());
        parameter01.setMerchantId(waitingUser.getMerchantId());
        parameter01.setActivateYn(waitingUser.getDeactivateActivateYn());
        parameter01.setModifyDate(waitingUser.getModifyDate());

        this.waitingUserDao.updateDeactivateUser(parameter01);

        WaitingUser parameter02 = new WaitingUser();

        parameter02.setIdWaitingUsers(waitingUser.getIdWaitingUsersNextTurnYn());
        parameter02.setMerchantId(waitingUser.getMerchantId());
        parameter02.setAdmissionYn(waitingUser.getNextTurnAdmissionYn());
        parameter02.setNextTurnYn(waitingUser.getNextTurnNextTurnYn());
        parameter01.setActivateYn(waitingUser.getActivateYn());
        parameter01.setModifyDate(waitingUser.getModifyDate());

        this.waitingUserDao.updateUserNextTurnYn(parameter02);
    }

    /**
     * 대기 목록을 가져 온다. iPad 에 출력 한다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public List<WaitingUser> selectUserList(WaitingUser waitingUser) {
        logger.info("selectUserList");
        return this.waitingUserDao.selectUserList(waitingUser);
    }

    /**
     * (오늘) 총 대기 인원 숫자를 가져 온다. iPad 에 출력 한다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserTotalCount(WaitingUser waitingUser) {
        logger.info("selectUserTotalCount");
        return this.waitingUserDao.selectUserTotalCount(waitingUser);
    }

    /**
     * 현재 대기자를 입장 처리 한다.
     *
     * @param waitingUser
     */
    @Override
    public void updateUserAdmissionYn(WaitingUser waitingUser) {
        logger.info("updateUserAdmissionYn");
        this.waitingUserDao.updateUserAdmissionYn(waitingUser);
    }

    /**
     * 다음 대기자의 next_turn_yn 의 값을 'Y' 로 업데이트 한다.
     *
     * @param waitingUser
     */
    @Override
    public void updateUserNextTurnYn(WaitingUser waitingUser) {
        logger.info("updateUserNextTurnYn");
        this.waitingUserDao.updateUserNextTurnYn(waitingUser);
    }

    /**
     * 현재 대기자를 입장 처리 하고 다음 대기자의 next_turn_yn 의 값을 'Y' 로 업데이트 한다.
     *
     * @param waitingUser
     */
    @Override
    public void updateUserAdmissionYnAndUserNextTurnYn(WaitingUser waitingUser) {
        logger.info("updateUserAdmissionYnAndUserNextTurnYn");

        WaitingUser parameter01 = new WaitingUser();

        parameter01.setMerchantId(waitingUser.getMerchantId());
        parameter01.setIdWaitingUsers(waitingUser.getIdWaitingUsersAdmissionYn());
        parameter01.setNextTurnYn(waitingUser.getAdmissionNextTurnYn());
        parameter01.setAdmissionYn(waitingUser.getAdmissionAdmissionYn());
        parameter01.setActivateYn(waitingUser.getActivateYn());
        parameter01.setModifyDate(waitingUser.getModifyDate());

        this.waitingUserDao.updateUserAdmissionYn(parameter01);

        WaitingUser parameter02 = new WaitingUser();

        parameter02.setMerchantId(waitingUser.getMerchantId());
        parameter02.setIdWaitingUsers(waitingUser.getIdWaitingUsersNextTurnYn());
        parameter02.setNextTurnYn(waitingUser.getNextTurnNextTurnYn());
        parameter02.setAdmissionYn(waitingUser.getNextTurnAdmissionYn());
        parameter02.setActivateYn(waitingUser.getActivateYn());
        parameter02.setModifyDate(waitingUser.getModifyDate());

        this.waitingUserDao.updateUserNextTurnYn(parameter02);
    }

    /**
     * 다음 대기자를 찾는다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserNextTurn(WaitingUser waitingUser) {
        logger.info("selectUserNextTurn");
        return this.waitingUserDao.selectUserNextTurn(waitingUser);
    }

    /**
     * 내 앞으로 남은 대기자 총 수를 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectRemainUserTotalCountBeforeMe(WaitingUser waitingUser) {
        logger.info("selectRemainUserTotalCountBeforeMe");
        return this.waitingUserDao.selectRemainUserTotalCountBeforeMe(waitingUser);
    }

    /**
     * 사용자가 대기 등록된 적이 있었는지 확인한다.
     * 추천 로직에서 사용한다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public WaitingUser selectUserRegistered(WaitingUser waitingUser) {
        logger.info("selectUserRegistered");
        return this.waitingUserDao.selectUserRegistered(waitingUser);
    }

    /**
     * 오늘 총 등록팀과 등록인원 정보를 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public List<WaitingUser> selectRegisterTeamAndUser(WaitingUser waitingUser) {
        logger.info("selectRegisterTeamAndUser");
        return this.waitingUserDao.selectRegisterTeamAndUser(waitingUser);
    }

    /**
     * 오늘 가장 최근에 등록/입장한 고객 2팀의 목록을 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public List<WaitingUser> selectRecentAdmissionUserList(WaitingUser waitingUser) {
        logger.info("selectRecentAdmissionUserList");
        return this.waitingUserDao.selectRecentAdmissionUserList(waitingUser);
    }

    /**
     * 오늘 등록/입장한 고객 목록을 가져 온다.
     *
     * @param waitingUser
     * @return
     */
    @Override
    public List<WaitingUser> selectTodayAdmissionUserList(WaitingUser waitingUser) {
        logger.info("selectTodayAdmissionUserList");
        return this.waitingUserDao.selectTodayAdmissionUserList(waitingUser);
    }
}
